home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 2
/
Atari Mega Archive CD - Volume 2.iso
/
minix
/
up1510b.tgz
/
up1510b
/
src
/
commands
/
cron.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-07-23
|
7KB
|
306 lines
/* Cron - clock daemon Author: S.R. Sampson */
/* Cron is the clock daemon. It is typically started up from the
* /etc/rc file by the line:
* /usr/bin/cron
* Cron automatically puts itself in the background, so no & is needed.
* If cron is used, it runs all day, spending most of its time asleep.
* Once a minute it wakes up and examines /usr/lib/crontab to see if there
* are any commands to be executed. The format of this table is the same
* as in UNIX, except that % is not allowed to indicate 'new line.'
*
* Each crontab entry has six fields:
* minute hour day-of-the-month month day-of-the-week command
* Each entry is checked in turn, and any entry matching the current time
* is executed. The entry * matches anything. Some examples:
*
* min hr dat mo day command
* * * * * * /usr/bin/date >/dev/tty0 #print date every minute
* 0 * * * * /usr/bin/date >/dev/tty0 #print date on the hour
* 30 4 * * 1-5 /bin/backup /dev/fd1 #do backup Mon-Fri at 0430
* 30 19 * * 1,3,5 /etc/backup /dev/fd1 #Mon, Wed, Fri at 1930
* 0 9 25 12 * /usr/bin/sing >/dev/tty0 #Xmas morning at 0900 only
*
* Version 1.6 SrT 90/04/08
* Added casting fixes by Ralf Wenk, and integrated net
* changes that release current directory, and use the
* 1.5.5 include files. Altered assign, so no temporary
* buffer is needed.
*
* Version 1.5 SrT 89/04/10
* Changed sleep code, to type SRS sent me.
*
* Version 1.4 SrT 89/03/17
* Fixed a pointer problem, when reloading crontab.
*
* Version 1.3 SrT 89/03/16
* Loads crontab, into memory and only rereads the disk
* version if it changes. (Free up those clock cycles!)
*
* Fixed 03/10/89, by Simmule Turner, simmy@nu.cs.fsu.edu
* Now correctly cleans up zombie processes
* Logs actions to /usr/adm/cronlog
* Syncs with clock after each minute
* Comments allowed in crontab
* Fixed bug that prevented month, from matching
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <time.h>
#include <string.h>
#include <fcntl.h>
#include <stdio.h>
#ifndef DEBUG
#define CRONTAB "/usr/lib/crontab"
#define LOGFILE "/usr/adm/cronlog"
#else
#define LOGFILE "/usr/adm/cronlog.dbg"
#define CRONTAB "/usr/adm/crontab.dbg"
#endif
#define NULLDEV "/dev/null"
#define SEPARATOR " \t"
#define CRONSIZE 2048
#define CRONSTRUCT struct cron_entry
#define TRUE 1
#define FALSE 0
struct cron_entry {
char *mn;
char *hr;
char *day;
char *mon;
char *wkd;
char *cmd;
struct cron_entry *next;
} *head, *entry_ptr;
char crontab[CRONSIZE];
FILE *cronlog;
int wakeup(), ret();
time_t previous_time = 0L;
main()
{
int status;
time_t clock;
status = fork();
if (status == -1) {
fprintf(stderr, "Can't fork cron\n");
exit(1);
}
if (status > 0) exit(0);
signal(SIGINT, SIG_IGN);
signal(SIGHUP, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
close(0);
close(1);
close(2);
chdir("/");
open(NULLDEV, O_RDONLY);
if ((cronlog = fopen(LOGFILE, "a")) == (FILE *) NULL) {
open(NULLDEV, O_WRONLY);
open(NULLDEV, O_WRONLY);
} else {
setbuf(cronlog, (char *) NULL);
dup(fileno(cronlog));
}
entry_ptr = (CRONSTRUCT *) malloc(sizeof(CRONSTRUCT));
entry_ptr->next = (CRONSTRUCT *) NULL;
head = entry_ptr;
while (TRUE) {
signal(SIGALRM, wakeup);
time(&clock);
alarm((unsigned) (60 - clock % 60));
pause();
signal(SIGALRM, ret);
alarm(1);
while (wait((int *) NULL) != (-1));
}
}
int ret() {}
wakeup()
{
register struct tm *tm;
time_t cur_time;
CRONSTRUCT *this_entry = head;
load_crontab();
time(&cur_time);
tm = localtime(&cur_time);
while (this_entry->next && this_entry->mn) {
if (match(this_entry->mn, tm->tm_min) &&
match(this_entry->hr, tm->tm_hour) &&
match(this_entry->day, tm->tm_mday) &&
match(this_entry->mon, tm->tm_mon + 1) &&
match(this_entry->wkd, tm->tm_wday)) {
fprintf(cronlog, "%02d/%02d-%02d:%02d %s\n",
tm->tm_mon + 1, tm->tm_mday, tm->tm_hour,
tm->tm_min, this_entry->cmd);
if (fork() == 0) {
execl("/bin/sh", "/bin/sh", "-c",
this_entry->cmd, (char *) 0);
exit(1);
}
}
this_entry = this_entry->next;
}
}
/*
* This routine will match the left string with the right number.
*
* The string can contain the following syntax *
* * This will return TRUE for any number
* x,y [,z, ...] This will return TRUE for any number given.
* x-y This will return TRUE for any number within
* the range of x thru y.
*/
match(left, right)
register char *left;
register int right;
{
register int n;
register char c;
n = 0;
if (!strcmp(left, "*")) return(TRUE);
while ((c = *left++) && (c >= '0') && (c <= '9')) n = (n * 10) + c - '0';
switch (c) {
case '\0':
return(right == n);
case ',':
if (right == n) return(TRUE);
do {
n = 0;
while ((c = *left++) && (c >= '0') && (c <= '9'))
n = (n * 10) + c - '0';
if (right == n) return(TRUE);
} while (c == ',');
return(FALSE);
case '-':
if (right < n) return(FALSE);
n = 0;
while ((c = *left++) && (c >= '0') && (c <= '9'))
n = (n * 10) + c - '0';
return(right <= n);
}
}
load_crontab()
{
int pos = 0;
FILE *cfp;
struct stat buf;
if (stat(CRONTAB, &buf)) {
if (previous_time == 0L) printf("Can't stat crontab\n");
previous_time = 0L;
return;
}
#ifdef DEBUG
printf("Crontab Time:%ld In_Core:%ld\n", buf.st_mtime, previous_time);
#endif
if (buf.st_mtime <= previous_time) return;
if ((cfp = fopen(CRONTAB, "r")) == (FILE *) NULL) {
if (previous_time == 0L) printf("Can't open crontab\n");
previous_time = 0L;
return;
}
previous_time = buf.st_mtime;
entry_ptr = head;
while (fgets(&crontab[pos], CRONSIZE - pos, cfp) != (char *) NULL) {
int len;
if (crontab[pos] == '#') continue;
len = strlen(&crontab[pos]);
if (crontab[pos + len - 1] == '\n') {
len--;
crontab[pos + len] = '\0';
}
assign(entry_ptr, &crontab[pos]);
if (entry_ptr->next == (CRONSTRUCT *) NULL) {
entry_ptr->next = (CRONSTRUCT *) malloc(sizeof(CRONSTRUCT));
entry_ptr->next->next = (CRONSTRUCT *) NULL;
}
entry_ptr = entry_ptr->next;
pos += ++len;
if (pos >= CRONSIZE) break;
}
fclose(cfp);
while (entry_ptr) {
entry_ptr->mn = (char *) NULL;
entry_ptr = entry_ptr->next;
}
#ifdef DEBUG
printf("Crontab uses %d/%d bytes\n", pos, CRONSIZE);
{
CRONSTRUCT *start = head;
dumptable(start);
}
#endif
}
assign(entry, line)
CRONSTRUCT *entry;
char *line;
{
entry->mn = strtok(line, SEPARATOR);
entry->hr = strtok((char *) NULL, SEPARATOR);
entry->day = strtok((char *) NULL, SEPARATOR);
entry->mon = strtok((char *) NULL, SEPARATOR);
entry->wkd = strtok((char *) NULL, SEPARATOR);
entry->cmd = strchr(entry->wkd,'\0') + 1;
}
#ifdef DEBUG
dumptable(table)
CRONSTRUCT *table;
{
time_t clock;
time(&clock);
printf("\nContents of crontab at: %s", ctime(&clock));
printf("Minute\tHour\tDay\tMonth\tWeekday\tCommand\n");
while (table->next && table->mn) {
printf("%s\t%s\t%s\t%s\t%s\t%s\n",
table->mn, table->hr, table->day, table->mon,
table->wkd, table->cmd);
table = table->next;
}
}
#endif